package com.dzt.cloudreader.base;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.dzt.cloudreader.R;
import com.dzt.cloudreader.interfaces.PerfectClickListener;
import com.dzt.cloudreader.utils.DialogMaker;
import com.dzt.cloudreader.utils.JLogKit;
import com.dzt.cloudreader.utils.JPreferenceKit;
import com.dzt.cloudreader.utils.JToastKit;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;

/**
 * Created by M02323 on 2018/01/13.
 * 封装了懒加载的实现
 * 如果是通过FragmentTransaction的show和hide的方法来控制显示，调用的是onHiddenChanged.
 * 当fragment可见状态改变时会触发的回调方法，和 Fragment 第一次可见时会回调的方法
 *
 * @see #onFragmentVisibleChange(boolean)
 * @see #onFragmentFirstVisible()
 */

public abstract class LazyFragment extends Fragment
        implements DialogMaker.DialogCallBack {
    protected Unbinder unbinder;
    protected Activity context;
    protected Bundle savedInstanceState;
    protected Dialog dialog;
    protected View view;
    protected View rootView;
    // fragment是否显示了
    protected boolean isVisible = false;
    //标志位，View已经初始化完成。
    protected boolean isPrepared = false;
    //是否第一次加载
    protected boolean isFirstLoad = true;
    // 加载中
    private LinearLayout mLlProgressBar;
    // 加载失败
    private LinearLayout mRefresh;
    // 内容布局
    protected RelativeLayout mContainer;
    // 动画
    private AnimationDrawable mAnimationDrawable;
    protected JPreferenceKit preferenceKit;
    private CompositeSubscription mCompositeSubscription;

    protected <T extends View> T getView(int id) {
        return (T) mContainer.findViewById(id);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.savedInstanceState = savedInstanceState;
        context = getActivity();
        preferenceKit = JPreferenceKit.getInstance();
        initVariable();
    }

    private void initVariable() {
        rootView = null;
        isVisible = false;
        isPrepared = false;
        isFirstLoad = true;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rView = inflater.inflate(R.layout.fragment_loading, null);
        view = inflater.inflate(getLayoutId(), null);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(params);
        mContainer = rView.findViewById(R.id.container);
        mContainer.addView(view);
        unbinder = ButterKnife.bind(this, view);

        mLlProgressBar = getView(R.id.ll_progress_bar);
        ImageView img = getView(R.id.img_progress);

        // 加载动画
        mAnimationDrawable = (AnimationDrawable) img.getDrawable();
        // 默认进入页面就开启动画
        if (!mAnimationDrawable.isRunning()) {
            mAnimationDrawable.start();
        }
        mRefresh = getView(R.id.ll_error_refresh);
        // 点击加载失败布局
        mRefresh.setOnClickListener(new PerfectClickListener() {
            @Override
            protected void onNoDoubleClick(View v) {
                showLoading();
                onRefresh();
            }
        });
        view.setVisibility(View.GONE);
        isPrepared = true;
        return rView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = view;
            if (getUserVisibleHint()) {
                if (isFirstLoad) {
                    onFragmentFirstVisible();
                    isFirstLoad = false;
                }
                onFragmentVisibleChange(true);
            }
        }
        super.onViewCreated(isPrepared ? rootView : view, savedInstanceState);
    }

    protected abstract int getLayoutId();

    protected abstract void initData();

    /**
     * 加载失败后点击后的操作
     */
    protected void onRefresh() {

    }

    /**
     * 如果是通过FragmentTransaction的show和hide的方法来控制显示，调用的是onHiddenChanged.
     * 若是初始就show的Fragment 为了触发该事件 需要先hide再show
     *
     * @param hidden hidden True if the fragment is now hidden, false if it is not
     *               visible.
     */
	@Override
	public void onHiddenChanged(boolean hidden) {
		super.onHiddenChanged(hidden);
		JLogKit.getInstance().e("onHiddenChanged hidden = " + hidden);
        if (rootView == null) {
            return;
        }
        if (!hidden && isFirstLoad) {
            onFragmentFirstVisible();
            isFirstLoad = false;
        }
        if (!hidden) {
            onFragmentVisibleChange(true);
            return;
        }
        if (isVisible) {
            onFragmentVisibleChange(false);
        }
	}

    /**
     * 去除setUserVisibleHint()多余的回调场景，保证只有当fragment可见状态发生变化时才回调
     * 回调时机在view创建完后，所以支持ui操作，解决在setUserVisibleHint()里进行ui操作有可能报null异常的问题
     * <p>
     * 可在该回调方法里进行一些ui显示与隐藏，比如加载框的显示和隐藏
     *
     * @param isVisible true  不可见 -> 可见
     *                  false 可见  -> 不可见
     */
    protected void onFragmentVisibleChange(boolean isVisible) {
        this.isVisible = isVisible;
    }

    /**
     * 在fragment首次可见时回调，可在这里进行加载数据，保证只在第一次打开Fragment时才会加载数据，
     * 这样就可以防止每次进入都重复加载数据
     * 该方法会在 onFragmentVisibleChange() 之前调用，所以第一次打开时，可以用一个全局变量表示数据下载状态，
     * 然后在该方法内将状态设置为下载状态，接着去执行下载的任务
     * 最后在 onFragmentVisibleChange() 里根据数据下载状态来控制下载进度ui控件的显示与隐藏
     */
    protected void onFragmentFirstVisible() {
        initData();
    }


    /**
     * 显示加载中状态
     */
    protected void showLoading() {
        if (mLlProgressBar.getVisibility() != View.VISIBLE) {
            mLlProgressBar.setVisibility(View.VISIBLE);
        }
        // 开始动画
        if (!mAnimationDrawable.isRunning()) {
            mAnimationDrawable.start();
        }
        if (view.getVisibility() != View.GONE) {
            view.setVisibility(View.GONE);
        }
        if (mRefresh.getVisibility() != View.GONE) {
            mRefresh.setVisibility(View.GONE);
        }
    }

    /**
     * 加载完成的状态
     */
    protected void showContentView() {
        if (mLlProgressBar.getVisibility() != View.GONE) {
            mLlProgressBar.setVisibility(View.GONE);
        }
        // 停止动画
        if (mAnimationDrawable.isRunning()) {
            mAnimationDrawable.stop();
        }
        if (mRefresh.getVisibility() != View.GONE) {
            mRefresh.setVisibility(View.GONE);
        }
        if (view.getVisibility() != View.VISIBLE) {
            view.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 加载失败点击重新加载的状态
     */
    protected void showError() {
        if (mLlProgressBar.getVisibility() != View.GONE) {
            mLlProgressBar.setVisibility(View.GONE);
        }
        // 停止动画
        if (mAnimationDrawable.isRunning()) {
            mAnimationDrawable.stop();
        }
        if (mRefresh.getVisibility() != View.VISIBLE) {
            mRefresh.setVisibility(View.VISIBLE);
        }
        if (view.getVisibility() != View.GONE) {
            view.setVisibility(View.GONE);
        }
    }

    public void addSubscription(Subscription s) {
        if (this.mCompositeSubscription == null) {
            this.mCompositeSubscription = new CompositeSubscription();
        }
        this.mCompositeSubscription.add(s);
    }

    @Override
    public void onBtnClicked(Dialog dialog, int position, Object tag) {

    }

    /**
     * pop dialog
     *
     * @param title
     * @param msg
     * @param btns
     * @param isCanCancelabel
     * @param isDismissAfterClickBtn
     * @return
     */
    public Dialog showAlertDialog(String title, String msg, String[] btns,
                                  boolean isCanCancelabel, final boolean isDismissAfterClickBtn,
                                  Object tag) {
        if (null == dialog || !dialog.isShowing()) {
            DialogMaker.showCommonAlertDialog(context, title, msg, btns, null,
                    isCanCancelabel, isDismissAfterClickBtn, tag);
        }
        return dialog;
    }

    public Dialog showWaitDialog(String msg, boolean isCanCancelabel, Object tag) {
        if (null == dialog || !dialog.isShowing()) {
            dialog = DialogMaker.showCommonWaitDialog(context, msg, null,
                    isCanCancelabel, tag);
        }
        return dialog;
    }

    protected void showToast(String msg) {
        JToastKit.getInstance().showMessage(msg);
    }

    /**
     * close dialog
     */
    public void dismissDialog() {
        if (null != dialog && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
        dismissDialog();
        if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
            mCompositeSubscription.unsubscribe();
        }
        isPrepared = false;
    }

    protected void startActivity(Class<?> cls, Intent intent) {
        if (null == intent) {
            intent = new Intent(context, cls);
        } else {
            intent.setClass(context, cls);
        }
        startActivity(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        initVariable();
    }
}